﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DSheet.Core.Data
{
    public class ComboDim : IEnumerable<DocDim>
    {
        public List<DocDim> Dims { get; set; }

        public DRelationChain RelationChain { get; set; }

        public ComboDim()
        {
            Dims = new List<DocDim>();
        }

        public DocDim this[int index]
        {
            get
            {
                return Dims[index];
            }
            set
            {
                Dims[index] = value;
            }
        }

        public int Count
        {
            get
            {
                return Dims.Count;
            }
        }

        public void Add(DocDim docDim)
        {
            Dims.Add(docDim);
        }

        public void RemoveAt(int index)
        {
            Dims.RemoveAt(index);
        }

        public void Insert(int index, DocDim docItem)
        {
            Dims.Insert(index, docItem);
        }

        public IEnumerator<DocDim> GetEnumerator()
        {
            return Dims.GetEnumerator();
        }

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return Dims.GetEnumerator();
        }

        /// <summary>
        /// 计算维度树
        /// </summary>
        /// <returns></returns>
        public DTree CalcDTree(DContext context)
        {
            if (RelationChain == null)
            {
                RelationChain = new DRelationChain();
                for (int index = 1; index < Dims.Count; index++)
                {
                    DocDim pdim = Dims[index -1];
                    DocDim dim = Dims[index];

                    RelationChain.Append(new DDRelation(pdim, dim));
                }
            }

            DocDim firstDim = Dims[0];
            DRelation firstRelation = this.RelationChain.First();

            DimData data = firstDim.GetData(context);
            DTree tree = data.ConvertToTree();
            tree.Dim = this;

            Stack<DTreeNode> stack = new Stack<DTreeNode>();
            foreach (var node in tree.Nodes)
            {
                stack.Push(node);
            }

            if (firstRelation != null)
            {
                while (stack.Count > 0)
                {
                    DTreeNode node = stack.Pop();
                    node.NextTree = firstRelation.GetTree(context, node);

                    foreach (var subNode in node.Nodes)
                    {
                        stack.Push(subNode);
                    }
                }
            }
            else
            {
                while (stack.Count > 0)
                {
                    DTreeNode node = stack.Pop();
                    foreach (var subNode in node.Nodes)
                    {
                        stack.Push(subNode);
                    }
                }
            }

            return tree;
        }
    }
}
